import { h } from 'snabbdom/src/package/h'
import { init } from 'snabbdom/src/package/init'
// 注册模块
import { styleModule } from 'snabbdom/src/package/modules/style'
import { classModule } from 'snabbdom/src/package/modules/class'
import { eventListenersModule } from 'snabbdom/src/package/modules/eventlisteners'
import { propsModule } from 'snabbdom/src/package/modules/props'

// 数据声明定义
const patch = init([
  styleModule,
  classModule,
  eventListenersModule,
  propsModule
])
var vnode

var nextKey = 6        
var margin = 8
var sortBy = 'rank'
var totalHeight = 0
var originalData = [
  { rank: 1, title: '习近平对制止餐饮浪费行为作出重要指示', desc: 'Two imprisoned men bond over a number of years, finding solace and eventual redemption through acts of common decency.', elmHeight: 0 },
  { rank: 2, title: '习近平指导筑牢住房安全“屏障” 央视快评', desc: 'The aging patriarch of an organized crime dynasty transfers control of his clandestine empire to his reluctant son.', elmHeight: 0 },
  { rank: 3, title: '黎智英被捕 25箱证物之下他必将被钉在历史耻辱柱上', desc: 'The early life and career of Vito Corleone in 1920s New York is portrayed while his son, Michael, expands and tightens his grip on his crime syndicate stretching from Lake Tahoe, Nevada to pre-revolution 1958 Cuba.', elmHeight: 0 },
  { rank: 4, title: '黎巴嫩总理宣布政府辞职：爆炸是地方腐败的结果', desc: 'When the menace known as the Joker wreaks havoc and chaos on the people of Gotham, the caped crusader must come to terms with one of the greatest psychological tests of his ability to fight injustice.', elmHeight: 0 },
  { rank: 5, title: '美记者进入武汉病毒所 所长驳斥:我们被当作替罪羊', desc: 'The lives of two mob hit men, a boxer, a gangster\'s wife, and a pair of diner bandits intertwine in four tales of violence and redemption.', elmHeight: 0 },
]
var data = [
  originalData[0],
  originalData[1],
  originalData[2],
  originalData[3],
  originalData[4],
]
// 排序
function changeSort (prop) {
  sortBy = prop
  data.sort((a, b) => {
    if (a[prop] > b[prop]) {
      return 1
    }
    if (a[prop] < b[prop]) {
      return -1
    }
    return 0
  })
  render()
}
// 增加一条数据
function add () {
  var n = originalData[Math.floor(Math.random() * 10)]
  data = [{ rank: nextKey++, title: n.title, desc: n.desc, elmHeight: 0 }].concat(data)
  render()
  render()
}
function remove (movie) {
  data = data.filter((m) => {
    return m !== movie
  })
  render()
}
function render () {
  data = data.reduce((acc, m) => {
    var last = acc[acc.length - 1]
    m.offset = last ? last.offset + last.elmHeight + margin : margin
    return acc.concat(m)
  }, [])
  totalHeight = data[data.length - 1].offset + data[data.length - 1].elmHeight
  vnode = patch(vnode, view(data))
}
// 创建列表中的每一行数据
function movieView (movie) {
  return h('div.row', {
    key: movie.rank,
    style: {
      opacity: '0',
      transform: 'translate(-200px)',
      delayed: { transform: `translateY(${movie.offset}px)`, opacity: '1' },
      remove: { opacity: '0', transform: `translateY(${movie.offset}px) translateX(200px)` }
    },
    hook: { insert: (vnode) => { movie.elmHeight = vnode.elm.offsetHeight } },
  }, [
    h('div', { style: { fontWeight: 'bold' } }, movie.rank),
    h('div', movie.title),
    h('div', movie.desc),
    h('div.btn.rm-btn', { on: { click: [remove, movie] } }, 'x'),
  ])
}
// 创建电影的list列表的VNode
function view (data) {
  return h ('div#container',[
    h ('h1', 'TOP 5 TOPIC'),
    h('div', [
      h('a.btn.add', { on: { click: add } }, 'Add'),
      'Sort by: ',
      h('span.btn-group', [
        h('a.btn.rank', { class: { active: sortBy === 'rank' }, on: { click: [changeSort, 'rank'] } }, 'Rank'),
        h('a.btn.title', { class: { active: sortBy === 'title' }, on: { click: [changeSort, 'title'] } }, 'Title'),
        h('a.btn.desc', { class: { active: sortBy === 'desc' }, on: { click: [changeSort, 'desc'] } }, 'Description'),
      ]),
      h('div.list', { style: { height: totalHeight + 'px' } }, data.map(movieView)),
    ]),
  ])
}
// DOM加载完成后触发事件
window.addEventListener('DOMContentLoaded', () => {
  var container = document.getElementById('app')
  vnode = patch(container, view(data))
  render()
})